// Copyright 2021 Tencent Inc. All rights reserved.
//
// 商家转账对外API（2025年1月15日升级版本）
//
// 下载电子回单
// [https://pay.weixin.qq.com/doc/v3/merchant/4013866774](https://pay.weixin.qq.com/doc/v3/merchant/4013866774)
// 通过该接口，商户可以下载商家转账业务的电子回单。
// 下载电子回单后，需将实际电子回单的哈希值与从接口返回的哈希值进行比对，以确保数据的完整性。
//
// API version: 1.0.0

// Code generated by WechatPay APIv3 Generator based on [OpenAPI
// Generator](https://openapi-generator.tech); DO NOT EDIT.

package com.wechat.pay.java.service.mchtransfer.model;

import com.wechat.pay.java.core.exception.MalformedMessageException;
import com.wechat.pay.java.core.util.ShaUtil;

import java.io.InputStream;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;

/** DigestElecsignEntity */
public class DigestElecsignEntity {
    private final DigestInputStream digestInputStream;
    private final String hashValue;

    public DigestElecsignEntity(InputStream inputStream, String hashValue, String hashType) {
        MessageDigest md = getMessageDigestInstance(hashType);
        this.digestInputStream = new DigestInputStream(inputStream, md);
        this.hashValue = hashValue;
    }

    private MessageDigest getMessageDigestInstance(String hashType) {
        try {
            if ("SM3".equals(hashType)) {
                return MessageDigest.getInstance("SM3", "Kona");
            }
            return MessageDigest.getInstance(hashType);
        } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
            throw new MalformedMessageException("Unsupported hash_type: " + hashType, e);
        }
    }

    private String digestAndEncodeHex() {
        MessageDigest md = digestInputStream.getMessageDigest();
        byte[] hash = md.digest();

        return ShaUtil.toHexString(hash);
    }

    /**
     * 返回下载电子回单的输入流。当电子回单下载完成后，调用方应关闭该输入流。
     *
     * @return 下载电子回单的输入流。
     */
    public InputStream getInputStream() {
        return this.digestInputStream;
    }

    /**
     * * 通过计算摘要并同查询电子回单时获得的摘要对比，验证下载账单的完整性
     *
     * @return 如果验证结果为真，电子回单是完整准确，未经篡改的。如果为假，电子回单是不完整或被篡改，应清理之前保存的文件。
     */
    public final boolean verifyHash() {
        final String digest = digestAndEncodeHex();
        return digest.equalsIgnoreCase(hashValue);
    }
}